const querystring = require('querystring')
const handleBlogRouter = require('./src/router/blog')
const handleUserRouter = require('./src/router/user')
const { get, set } = require('./src/db/redis')

// userId为key session为val
// const SESSION_DATA = {}

// 用于处理 post data
const getPostData = (req) => {
    return new Promise((resolve, reject) => {
        if (req.method !== 'POST') {
            // 不是POST请求直接返回空对象
            resolve({})
            return 
        }
        if (req.headers['content-type'] !== 'application/json') {
            // 因为不是用框架
            // 不是json类型直接返回空对象
            resolve({})
            return
        }
        let postData = ''
        req.on('data', chunk => {
            postData += chunk.toString()
        })
        req.on('end', () => {
            if (!postData) {
                resolve({})
                return
            }
            resolve(
                JSON.parse(postData)
            )
        })
    })
}

// 获取 cookie 的过期时间
const getCookieExpires = () => {
    const d = new Date()
    d.setTime(d.getTime() + (24*60*60*1000))
    // console.log(d.toTimeString())
    return d.toTimeString()
}

async function serverHandle(req, res){
    //设置返回格式 JSON
    res.setHeader('Content-type', 'application/json')
    //获取 path
    const url = req.url
    req.path = url.split('?')[0]

    // 解析 query
    req.query = querystring.parse(url.split('?')[1])

    // 解析 cookie
    req.cookie = {}
    const cookieStr = req.headers.cookie || '' // k1=v1;k2=v2;k3=v3
    cookieStr.split(';').forEach(item => {
        if (!item) {
            return
        }
        const arr = item.split('=')
        const key = arr[0].trim()
        const val = arr[1].trim()
        req.cookie[key] = val
    })
   
    // if (userSession) {

    // }

    // 解析 session
    let needSetCookie = false
    let userSession = {}
    let userId = req.cookie.userid
    if (userId) {
        // [],null,undefined->false    {}->true
        userSession = await get(userId)
        // userSession = null
        // console.log("! null: ", !null)
        if (!userSession) {
            userSession = {}
            needSetCookie = true
        }
    } else {
        needSetCookie = true
        userId = `${Date.now()}_${Math.random()}`
        userSession =  {}
    }
    req.session = userSession
    // 解析 req 携带的 post data
    req.body = await getPostData(req)
    // console.log(req.body)

    // 处理 blog 路由
    // 成功的话：success对象，失败的话：err对象
    /*SuccessModel {
        data:
         [ { id: 1,
             title: '标题A',
             content: '内容A',
             createtime: 1546870338518,
             author: 'zhangsan' }]
    }*/
    // JSON.stringify() 这个方法可以去掉类名使其变为普通对象，并把普通对象字符串化
    const blogData = await handleBlogRouter(req, res)
    if (blogData) {   
        if (needSetCookie) {
            res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}` )
        }
        res.end(
            JSON.stringify(blogData)
        )
        return
    }

    // 处理 user 路由
    const userData = await handleUserRouter(req, res)
    if (userData) {
        if (needSetCookie) {
            res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}` )
            set(userId, req.session)
        }
        res.end(
            JSON.stringify(userData)
        )
        return
    }

    // 未命中路由，返回 404
    res.writeHead(404, { "Content-type": "text/plain" })
    res.write("404 Not Found\n")
    res.end()
}

module.exports = serverHandle

// process.env.NODE_ENV

// 关于回调地狱
/*const fs = require('fs')
const path = require('path')
function getFileContent(fileName, callback) {
    const fullFileName = path.resolve(__dirname, 'files', fileName)
    fs.readFile(fullFileName, (err, data) => {
        if (err) {
            console.error(err)
            return
        }
        callback(
            JSON.parse(data.toString)
        )
    })
}

// callback-hell
getFileContent('a.json', aData => {
    console.log('a data', aData)
    getFileContent(aData.next, bData => {
        console.log('b data', bData)
        getFileContent(bData.next, cData => {
            console.log('c data', cData)
        })
    })
})
*/

// 用promise获取文件内容
/*const fs = require("fs")
const path = require("path")
function getFileContent(fileName) {
    return new Promise((resolve, reject) => {
        const fullFileName = path.resolve(__dirname, 'files', fileName)
        fs.readFile(fullFileName, (err, data) => {
            if (err) {
                reject(err)
                return
            }
            resolve(
                JSON.parse(data.toString())
            )
        })
    })
}
// async/await只在函数调用时起作用，也就是说不能给getFileContent加上async/await 那样没有，只有给调用方加上
async function printData() {
    const aData = await getFileContent('a.json')
    console.log(aData)
    const bData = await getFileContent(aData.next)
    console.log(bData)
    const cData = await getFileContent(bData.next)
    console.log(cData)
}
printData()
*/




